﻿using SmallJob.Data;
using SmallJob.Data.Interfaces;
using SmallJob.Model;
using SmallJob.Services.Interfaces;
using SmallShop.Services.Code;
using System;
using System.Collections.Generic;
using System.Linq;

namespace SmallJob.Services.Implements
{
    public enum OrderType { PROVIDE = 1, REQUEST = 2 }
    public class OrderService : RepositoryBase<Order>, IOrderService
    {
        public OrderService(IDatabaseFactory DbFactory)
            : base(DbFactory)
        {
        }

        public List<Order> GetByUserID(int id)
        {
            var result = from o in SmallJobDB.Orders
                         where o.BuyerID == id && !o.IsDeleted
                         orderby o.CreatedDate descending
                         select o;
            return result.ToList();
        }

        public List<Order> GetAllOrderSell(int id)
        {
            var result = from o in SmallJobDB.Orders
                         where o.SellerID == id && !o.IsDeleted
                         orderby o.ModifiedDate descending
                         select o;
            return result.ToList();
        }

        public List<Order> GetAllOrderBuy(int id)
        {
            var result = from o in SmallJobDB.Orders
                         where o.BuyerID == id && !o.IsDeleted
                         orderby o.ModifiedDate descending
                         select o;
            return result.ToList();
        }

        public List<Order> GetAllOrderByUserId(int id)
        {
            var result = from o in SmallJobDB.Orders
                         where (o.BuyerID == id || o.SellerID == id) && (!o.Completed || o.Comment == null || o.Comment.Length <= 0) && !o.IsDeleted
                         orderby o.ModifiedDate descending
                         select o;
            return result.ToList();
        }

        public List<Order> GetOrderComment(int p)
        {
            var result = (from o in SmallJobDB.Orders
                          where o.ProvideID == p && o.Comment != null && o.Comment.Length > 0 && !o.IsDeleted
                          orderby o.ModifiedDate descending
                          select o);
            return result.ToList();
        }

        public List<Order> GetByPage(int page, int pagesize, out int total)
        {
            var list = from u in SmallJobDB.Orders
                       orderby u.ID descending
                       select u;
            int skip = (page - 1) * pagesize;
            total = list.ToList().Count;
            return list.Skip(skip).Take(pagesize).ToList();
        }
        public List<Order> GetByPageFilter(int page, int pagesize, out int total, string filter, string filterstatus, string filterpayment, string filtertype)
        {


            bool nofilter = string.IsNullOrWhiteSpace(filter);
            bool nofiltertype = (string.IsNullOrWhiteSpace(filtertype) || filtertype.Equals("-1"));
            bool nofilterstatus = (string.IsNullOrWhiteSpace(filterstatus) || filterstatus.Equals("-1"));
            bool nofilterpayment = (string.IsNullOrWhiteSpace(filterpayment) || filterpayment.Equals("-1"));
            int inttype = -1;
            Int32.TryParse(filtertype, out inttype);
            int intstatus = -1;
            Int32.TryParse(filterstatus, out intstatus);
            int intpayment = -1;
            Int32.TryParse(filterpayment, out intpayment);



            var listBuyer = from o in SmallJobDB.Orders
                            join u in SmallJobDB.Users on o.BuyerID equals u.ID
                            where (nofilter || u.ProperName.Contains(filter)) &&
                             (nofiltertype || inttype == -1 || o.Type == inttype) &&
                             (nofilterstatus || intstatus == -1 || o.Status == intstatus) &&
                             (nofilterpayment || intpayment == -1 || o.PaymentStatus == intpayment)
                            orderby o.ID descending
                            select o;
            var listSeller = from o in SmallJobDB.Orders
                             join u in SmallJobDB.Users on o.SellerID equals u.ID
                             where (nofilter || u.ProperName.Contains(filter)) &&
                             (nofiltertype || inttype == -1 || o.Type == inttype) &&
                             (nofilterstatus || intstatus == -1 || o.Status == intstatus) &&
                             (nofilterpayment || intpayment == -1 || o.PaymentStatus == intpayment)
                             orderby o.ID descending
                             select o;
            var listProvide = from o in SmallJobDB.Orders
                              where o.Type == 1
                              join p in SmallJobDB.Provides on o.ProvideID equals p.ID
                              where (nofilter || p.Title.Contains(filter)) &&
                             (nofiltertype || inttype == -1 || o.Type == inttype) &&
                             (nofilterstatus || intstatus == -1 || o.Status == intstatus) &&
                             (nofilterpayment || intpayment == -1 || o.PaymentStatus == intpayment)
                              orderby o.ID descending
                              select o;
            var listRequest = from o in SmallJobDB.Orders
                              where o.Type == 2
                              join r in SmallJobDB.Requests on o.RequestID equals r.ID
                              where (nofilter || r.Title.Contains(filter)) &&
                             (nofiltertype || inttype == -1 || o.Type == inttype) &&
                             (nofilterstatus || intstatus == -1 || o.Status == intstatus) &&
                             (nofilterpayment || intpayment == -1 || o.PaymentStatus == intpayment)
                              orderby o.ID descending
                              select o;

            int skip = (page - 1) * pagesize;
            var list = new List<Order>();
            list.AddRange(listBuyer.ToList());
            list.AddRange(listSeller.ToList());
            list.AddRange(listProvide.ToList());
            list.AddRange(listRequest.ToList());
            total = list.Count();
            return list.OrderByDescending(o => o.CreatedDate).Skip(skip).Take(pagesize).ToList();
        }

        public List<Order> GetAllOrderWorker(int userid)
        {
            var lst = (from o in SmallJobDB.Orders
                       where o.SellerID == userid && o.Status != (int)OrderStatusV2.NoActive && (!o.DisableDetails || o.Status == (int)OrderStatusV2.Done)
                       orderby o.ModifiedDate descending
                       select o).ToList();
            return lst;
        }

        public List<Order> GetAllOrderPayer(int userid)
        {
            var lst = (from o in SmallJobDB.Orders
                       where o.BuyerID == userid && o.Status != (int)OrderStatusV2.NoActive && (!o.DisableDetails || o.Status == (int)OrderStatusV2.Done)
                       orderby o.ModifiedDate descending
                       select o).ToList();
            return lst;
        }


        public int CountServiceProcess(int userid)
        {
            var lst = new List<int>();
            lst.Add((int)OrderStatusV2.InProgress);
            lst.Add((int)OrderStatusV2.Rejected);
            lst.Add((int)OrderStatusV2.WaitDone);
            lst.Add((int)OrderStatusV2.WaitProgress);
            var result = (from o in SmallJobDB.Orders
                          where o.SellerID == userid && lst.Contains(o.Status) && !o.DisableDetails
                          select o).Count();
            return result;
        }

        public int CountOrderWaitDone(int userid)
        {
            var lst = new List<int>();
            lst.Add((int)OrderStatusV2.InProgress);
            lst.Add((int)OrderStatusV2.Rejected);
            lst.Add((int)OrderStatusV2.WaitDone);
            lst.Add((int)OrderStatusV2.WaitProgress);
            var result = (from o in SmallJobDB.Orders
                          where o.BuyerID == userid && lst.Contains(o.Status) && !o.DisableDetails
                          select o).Count();
            return result;
        }
    }
}